/*******************************************************************************
 * Copyright 2011 Towee.net
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *******************************************************************************/
package net.towee.server;

import java.io.IOException;

import net.towee.server.authentication.impl.AuthenticationFilter;
import net.towee.server.authentication.impl.EmailAuthServlet;
import net.towee.server.authentication.impl.LoginzaAuthServlet;
import net.towee.server.authentication.impl.LogoutServlet;
import net.towee.server.ftp.ToweeFtpServer;
import net.towee.server.persistence.PersistenceModule;
import net.towee.server.rpc.servlet.AttachmentServlet;
import net.towee.server.rpc.servlet.AuthenticationServlet;
import net.towee.server.rpc.servlet.NoCacheFilter;
import net.towee.server.rpc.servlet.ToweeClientServlet;
import net.towee.server.rpc.servlet.ToweeServiceServlet;
import net.towee.server.util.settings.SettingsBinder;
import net.towee.shared.exceptions.PersistenceException;

import org.apache.commons.configuration.ConfigurationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Module;

/**
 * Towee server entrypoint
 * 
 * @author c58
 */
public class ServerMain {
	/**
	* This is the name of the system property used to find the server config file.
	*/
	private  static final String PROPERTIES_FILE_KEY = "net.towee.config";
	private static final Logger LOG = LoggerFactory.getLogger(ServerMain.class);
	
	public static void main(String[] args) {
	    try {
	        Module coreSettings = SettingsBinder.bindSettings(PROPERTIES_FILE_KEY, CoreSettings.class);
	        run(coreSettings);
	        return;
	      } catch (IOException e) {
	        LOG.error("IOException when running server:", e);
	      } catch (PersistenceException e) {
	        LOG.error("PersistenceException when running server:", e);
	      } catch (ConfigurationException e) {
	        LOG.error("ConfigurationException when running server:", e);
	      }
	}

	public static void run(Module coreSettings) throws IOException, PersistenceException,
    	ConfigurationException {

		// Initialize injector
	    Injector settingsInjector = Guice.createInjector(coreSettings);
	    PersistenceModule persistenceModule = settingsInjector.getInstance(PersistenceModule.class);
	    Injector injector = settingsInjector.createChildInjector(new ServerModule(), persistenceModule);
	    
	    // Create FTP server
	    ToweeFtpServer ftpServer = injector.getInstance(ToweeFtpServer.class);
	    ftpServer.start();

	    // Set servlets and filters
	    ServerRpcProvider server = injector.getInstance(ServerRpcProvider.class);
	    server.addServlet("/", injector.getInstance(ToweeClientServlet.class));
	    server.addServlet("/auth", injector.getInstance(AuthenticationServlet.class));
	    server.addServlet("/logout", injector.getInstance(LogoutServlet.class));
	    server.addServlet("/auth/loginza", injector.getInstance(LoginzaAuthServlet.class));
	    server.addServlet("/auth/email", injector.getInstance(EmailAuthServlet.class));
	    server.addServlet("/attachment/*", injector.getInstance(AttachmentServlet.class));
	    server.addServlet("/socket.io/*", injector.getInstance(ToweeServiceServlet.class));
	    
	    // Authentication filters
	    server.addFilter("/attachment/*", injector.getInstance(AuthenticationFilter.class));
	    server.addFilter("/socket.io/*", injector.getInstance(AuthenticationFilter.class));
	    
	    // No cache filter
	    server.addFilter("/ui/ui.nocache.js", injector.getInstance(NoCacheFilter.class));
	    
	    // Start the main server
	    server.startServer();
	}
}
